/****************************************************************\
*                                                                *
*  Utilities to facilitate code generation DP implementations    *
*                                                                *
*  Guy St.C. Slater..   mailto:guy@ebi.ac.uk                     *
*  Copyright (C) 2000-2009.  All Rights Reserved.                *
*                                                                *
*  This source code is distributed under the terms of the        *
*  GNU General Public License, version 3. See the file COPYING   *
*  or http://www.gnu.org/licenses/gpl.txt for details            *
*                                                                *
*  If you use this code, please keep this notice intact.         *
*                                                                *
\****************************************************************/

#include "cgutil.h"

void CGUtil_print_header(Codegen *codegen, C4_Model *model){
    register gint i;
    Codegen_printf(codegen,
        "/* Code automatically generated by C4 DP library\n"
        " * Do not attempt to edit this code: it is spagetti.\n"
        " *\n"
        " * Model: %s\n"
        " */\n\n"
        " /* ---< START >--- */\n\n", model->name);
    for(i = 0; i < model->global_code_list->len; i++)
        Codegen_printf(codegen, model->global_code_list->pdata[i]);
    Codegen_printf(codegen, "\n");
    return;
    }

void CGUtil_print_footer(Codegen *codegen){
    Codegen_printf(codegen, "/* ---< END >--- */\n\n");
    return;
    }

void CGUtil_compile(Codegen *codegen, C4_Model *model){
    register gint i;
    register GString *cflags;
    cflags = g_string_new(  " -I" SOURCE_ROOT_DIR "/src/c4");
    g_string_append(cflags, " -I" SOURCE_ROOT_DIR "/src/struct");
    g_string_append(cflags, " -I" SOURCE_ROOT_DIR "/src/general");
    g_string_append(cflags, " -I" SOURCE_ROOT_DIR "/src/sequence");
    g_string_append(cflags, " " GLIB_CFLAGS);
    for(i = 0; i < model->cflags_add_list->len; i++)
        g_string_append(cflags,
                        model->cflags_add_list->pdata[i]);
    Codegen_compile(codegen, cflags->str, NULL);
    g_string_free(cflags, TRUE);
    return;
    }

void CGUtil_prep(Codegen *codegen, C4_Model *model, gboolean is_init){
    register gint i;
    register C4_Calc *calc;
    register C4_PrepFunc prep_func;
    register gchar *macro, *type = is_init ? "init" : "exit";
    /**/
    if(is_init){
        if(model->init_macro){
            Codegen_printf(codegen, "%s;\n", model->init_macro);
        } else {
            if(model->init_func){
                Codegen_printf(codegen,
                    "model->init_func(region, user_data);\n");
                }
            }
        }
    /**/
    Codegen_printf(codegen, "/* Transition calc %s */\n", type);
    for(i = 0; i < model->calc_list->len; i++){
        calc = model->calc_list->pdata[i];
        macro = is_init ? calc->init_macro : calc->exit_macro;
        if(macro){
            Codegen_printf(codegen, "%s;\n", macro);
        } else {
            prep_func = is_init ? calc->init_func : calc->exit_func;
            if(prep_func){
                Codegen_printf(codegen,
                    "calc = model->calc_list->pdata[%d];\n", i);
                Codegen_printf(codegen,
                    "calc->%s_func(region, user_data);\n", type);
                }
            }
        }
    /**/
    if(!is_init){
        if(model->exit_macro){
            Codegen_printf(codegen, "%s;\n", model->exit_macro);
        } else {
            if(model->exit_func){
                Codegen_printf(codegen,
                    "model->exit_func(region, user_data);\n");
                }
            }
        }
    /**/
    return;
    }

/**/

